package org.example.config;

import org.springframework.amqp.core.*;
import org.springframework.amqp.rabbit.connection.ConnectionFactory;
import org.springframework.amqp.rabbit.core.RabbitAdmin;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.amqp.support.converter.Jackson2JsonMessageConverter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.HashMap;
import java.util.Map;

/**
 *@ClassName: RabbitConfig
 *@Author: CJ
 *@Date: 2021-9-26 21:27
 */
@Configuration
public class RabbitConfig {

    // 延时交换机
    public static final String DELAY_EXCHANGE_NAME = "delay_exchange";

    // 延时队列名称
    public static final String DELAY_QUEUE_NAME = "delay_queue";

    // 普通交换机
    public static final String ORDER_PAY_Exchange_Name = "order_pay_exchange";

    // 普通队列名称
    public static final String ORDER_PAY_QUEUE_NAME = "order_pay_queue";

    // 普通交换机路由键
    public static final String ORDER_PAY_ROUTING_KEY = "order_pay_routing_key";

    // ------------------------延时队列------------------------
    // 延时队列
    @Bean
    public Queue delayPayQueue() {
        return new Queue(RabbitConfig.DELAY_QUEUE_NAME, true);
    }

    // 延时交换机
    public FanoutExchange delayExchange() {
        Map<String, Object> args = new HashMap<>();
        args.put("x-delayed-type", "direct");
        FanoutExchange fanoutExchange = new FanoutExchange(RabbitConfig.DELAY_EXCHANGE_NAME, true, false, args);
        fanoutExchange.setDelayed(true);
        return fanoutExchange;
    }

    // 绑定延时队列与延时交换机
    @Bean
    public Binding delayPayBind() {
        return BindingBuilder.bind(delayPayQueue()).to(delayExchange());
    }

    // ------------------------普通队列------------------------
    // 普通队列
    @Bean
    public Queue orderPayQueue() {
        return new Queue(RabbitConfig.ORDER_PAY_QUEUE_NAME, true);
    }

    // 普通交换机
    @Bean
    public DirectExchange orderExchange() {
        return new DirectExchange(RabbitConfig.ORDER_PAY_Exchange_Name, true, false);
    }

    // 绑定普通消息队列
    @Bean
    public Binding orderPayBind() {
        return BindingBuilder.bind(orderPayQueue()).to(orderExchange()).with(RabbitConfig.ORDER_PAY_ROUTING_KEY);
    }

    // 定义消息转换器
    @Bean
    public Jackson2JsonMessageConverter jsonMessageConverter() {
        return new Jackson2JsonMessageConverter();
    }

    // 定义消息模板用于发布消息，并且设置其消息转换器
    @Bean
    public RabbitTemplate rabbitTemplate(ConnectionFactory connectionFactory) {
        final RabbitTemplate rabbitTemplate = new RabbitTemplate(connectionFactory);
        rabbitTemplate.setMessageConverter(jsonMessageConverter());
        return rabbitTemplate;
    }

    // --------------------------使用RabbitAdmin启动服务便创建交换机和队列--------------------------
    @Bean
    public RabbitAdmin rabbitAdmin(ConnectionFactory connectionFactory) {
        RabbitAdmin rabbitAdmin = new RabbitAdmin(connectionFactory);
        // 只有设置为 true，spring 才会加载 RabbitAdmin 这个类
        rabbitAdmin.setAutoStartup(true);
        // 创建延时交换机和对列
        rabbitAdmin.declareExchange(delayExchange());
        rabbitAdmin.declareQueue(delayPayQueue());
        // 创建普通交换机和对列
        rabbitAdmin.declareExchange(orderExchange());
        rabbitAdmin.declareQueue(orderPayQueue());
        return new RabbitAdmin(connectionFactory);
    }
}
